package userInterface;

import com.sun.javafx.scene.paint.GradientUtils;
import core.demo.BubbleSort;
import core.demo.ChooseSort;
import core.demo.QuickSort;
import core.obj.Sort;
import javafx.util.Pair;
import userInterface.tool.Bar;
import userInterface.tool.Pointer;

import javax.sound.midi.Soundbank;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

//主要的窗口
public class MainWindow extends JFrame implements Runnable{
        private int index=0;
        private MainWindow me=this;
        private Integer[] origin;
        private Integer[] numbers;
        private int count;
        private int sortIndex;
        private Vector<Pair<Integer,Integer>> process;//交换过程
        private Vector<Pair<Integer,Integer>> pointerPro;//指针过程
        private Bar[] bars;
        private Vector<Pair<Integer,Bar>> fuckers;
        private BarPane barPane;
        private PointerPane pointerPane;
        private ControlPane controlPane;
        private int barP;//模拟指向process数组的指针;
        private int pointerP;//模拟指向pointers数组的指针;
        private boolean halt;
        Pointer[] pointers;

        public MainWindow(InputDialog inputDialog){
                super("排序演示");
                barP=0;pointerP=0;halt=false;count=inputDialog.getNumbers().length;
                numbers=getInteger(inputDialog.getNumbers());
                origin=getInteger(inputDialog.getNumbers());
                sortIndex=inputDialog.getSortIndex();
                Sort<Integer> theSort = sort();
                process= theSort.getProcess();
                for (Pair<Integer,Integer> p:process)
                {
                        System.out.println("process:"+p);
                }
                pointerPro= theSort.getPointers();
                for (Pair<Integer,Integer> p:pointerPro)
                {
                        System.out.println("pointer"+p);
                }
                barPane=new BarPane();
                pointerPane=new PointerPane();
                controlPane=new ControlPane();
                setUI();

        }
        private void reverse() throws InterruptedException {
                //todo
                if(pointerP>0) {
                        pointerP--;
                }
                Pair<Integer,Integer> pair=pointerPro.get(pointerP);
                pointers[1].movX(new Point(fuckers.get(pair.getValue()).getKey(),650));
                pointers[0].movX(new Point(fuckers.get(pair.getKey()).getKey(),650));
                System.out.println("每步数对："+pointerPro.get(pointerP)+",pointerP的当前大小："+pointerP);
                if(barP>0)
                {
                        barP--;
                }
                if (pointerPro.get(pointerP).equals(process.get(barP))) {
                        System.out.println("当前要交换的数对："+process.get(barP)+",barP的当前大小："+barP);
//                        swap(bars[process.get(barP).getKey()],bars[process.get(barP).getValue()]);//交换这两个bar
                        swap(process.get(barP).getKey(),process.get(barP).getValue());//交换这两个bar

                }
        }
        public void operation() throws InterruptedException,ArrayIndexOutOfBoundsException{//单步的操作,包括pointerP++,movPointer,判断并swapBar(),barP++;
                for (Pair<Integer,Integer> p:process)
                {
                        System.out.println(p);
                }
                if (pointerPro.get(pointerP).equals(process.get(barP))) {
                        System.out.println("当前要交换的数对："+process.get(barP)+",barP的当前大小："+barP);
//                        swap(bars[process.get(barP).getKey()],bars[process.get(barP).getValue()]);//交换这两个bar
                        swap(process.get(barP).getKey(),process.get(barP).getValue());//交换这两个bar
                        if(barP<process.size()-1)
                        {
                                barP++;
                        }
                }
                System.out.println("每步数对："+pointerPro.get(pointerP)+",pointerP的当前大小："+pointerP);
                if(pointerP<pointerPro.size()-1) {
                        pointerP++;
                }else {
                        controlPane.forwordB.setEnabled(false);
                        controlPane.pauseB.setEnabled(false);
                        controlPane.startB.setEnabled(false);
                        controlPane.backB.setEnabled(true);
                        halt=true;
                        return;
                }
                Pair<Integer,Integer> pair=pointerPro.get(pointerP);
                pointers[1].movX(new Point(fuckers.get(pair.getValue()).getKey(),650));
                pointers[0].movX(new Point(fuckers.get(pair.getKey()).getKey(),650));
                controlPane.backB.setEnabled(true);
                controlPane.forwordB.setEnabled(true);
                controlPane.pauseB.setEnabled(true);
                controlPane.startB.setEnabled(true);

        }

        private void swap(int m,int n) throws InterruptedException {//交换bar的方法
                Bar a = fuckers.get(m).getValue();
                Bar b = fuckers.get(n).getValue();

                Bar barN=fuckers.get(n).getValue();
                int xM=fuckers.get(m).getKey();
                fuckers.set(n,new Pair<>(fuckers.get(n).getKey(),fuckers.get(m).getValue()));
                fuckers.set(m,new Pair<>(xM,barN));
                Point bPoint=new Point(b.getPoint().x,b.getPoint().y);
                Point aPoint=new Point(a.getPoint().x,a.getPoint().y);
                Point temp=new Point(aPoint.x,aPoint.y);
                aPoint.y-=350;
                a.movY(aPoint);
                a.movX(bPoint);
                b.movX(temp);
                aPoint.y+=350;
                a.movY(aPoint);
        }
        private Integer[] getInteger(int[] numbers) {
                System.out.println("传入的普通int型数组的大小："+numbers.length);
                Integer[] integers=new Integer[numbers.length];
                for(int i=0;i<numbers.length;i++){
                        integers[i]=numbers[i];
                }
               return  integers;
        }

        private Sort<Integer> sort(){
                System.out.println("创建sort对象");
                switch (sortIndex){
                    case 1: return new BubbleSort<>(numbers);
                    case 2: return new ChooseSort<>(numbers);
                    case 3: return new QuickSort<>(numbers);
                    default:return null;
            }
        }
        private void setUI() {
                //todo
                //panel的设置
                controlPane.setBounds(0,700,1000,100);
                barPane.setBackground(new Color(255, 200, 67));
                pointerPane.setBounds(0,650,1000,50);
                barPane.setBounds(0,0,1000,650);
                //整体布局
                setVisible(true);
                setSize(1000,800);
                setLayout(null);
                setLocationRelativeTo(null);
                setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                //添加
                add(controlPane);
                add(pointerPane);
                add(barPane);
        }

        @Override
        public void run() {
                try {
                        if(index==1) {
                                operation();
                        }
                        if (index==2)
                        {
                                reverse();
                        }
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
        }


        private class BarPane extends JPanel{
                public BarPane(){
                        super();
                        initBar();
                        setUI();
                }

                private void initBar() {
                        bars=new Bar[count];
                        int width=1000/(2*count+1);
                        fuckers = new Vector<>();
                        Vector<Pair<Integer,Integer>> rank=getRank();
                        for(int i=0;i<count;i++){
                                int height=((rank.get(i).getValue())+1)*(300/count);
                                bars[i]=new Bar(new Rectangle(width*(2*i+1),650-height,width,height),origin[i]);
                                fuckers.add(new Pair<>(width*(2*i+1),bars[i]));
                                add(bars[i]);
                        }
                }

                private Vector<Pair<Integer, Integer>> getRank() {
                        Vector<Pair<Integer,Integer>> temp=new Vector<>();
                        for(int i=0;i<count;i++){
                                int weight=0;
                                for (int j=0;j<count;j++){
                                        if(origin[i]>origin[j])weight++;
                                }
                                temp.addElement(new Pair<>(origin[i],weight));
                        }
                        return temp;
                }


                public void setUI(){
                        //todo
                        setLayout(null);
                }
        }

        private class PointerPane extends JPanel{
                public PointerPane(){
                        super();
                        initPointer();
                        setUI();
                }

                private void initPointer() {
                     pointers=new Pointer[2];
                     pointers[0]=new Pointer(new Rectangle(bars[pointerPro.get(0).getKey()].getX(),0,1000/(2*count)+1,50));
                     pointers[1]=new Pointer(new Rectangle(bars[pointerPro.get(0).getValue()].getX(),0,1000/(2*count)+1,50));
                }

                public void setUI(){
                        //todo
                        setLayout(null);
                        add(pointers[0]);
                        add(pointers[1]);
                }
        }

        private class ControlPane extends JPanel implements ActionListener {
                JButton backB,forwordB,startB,pauseB;
                public ControlPane(){
                        super();
                        backB=new JButton("后退");
                        forwordB=new JButton("单步前进");
                        startB=new JButton(" 开始演示");
                        pauseB=new JButton("暂停");
                        setUI();
                        backB.addActionListener(this);
                        forwordB.addActionListener(this);
                        startB.addActionListener(this);
                        pauseB.addActionListener(this);

                }

                private void setUI() {
                        //todo
                        setLayout(null);
                        pauseB.setEnabled(false);
                        backB.setEnabled(false);
                        backB.setBounds(150,0,100,30);
                        pauseB.setBounds(350,0,100,30);
                        forwordB.setBounds(550,0,100,30);
                        startB.setBounds(750,0,100,30);
                        //监听器的添加
                        add(backB);
                        add(pauseB);
                        add(forwordB);
                        add(startB);
                }

                @Override
                public void actionPerformed(ActionEvent e) {
                        Object Button=e.getSource();
                        if(Button== backB){
                                index=2;//代表回退
                                Thread t=new Thread(me);
                                t.start();
                        }else if(Button==forwordB){
                                try {
                                        backB.setEnabled(false);
                                        forwordB.setEnabled(false);
                                        pauseB.setEnabled(false);
                                        startB.setEnabled(false);
                                        index=1;//正向单步
                                        Thread t=new Thread(me);
                                        t.start();
                                } catch (ArrayIndexOutOfBoundsException a)
                                {
                                        System.out.println("越界");
                                }
                        }else if(Button==startB){
                                pauseB.setEnabled(true);
                                Start s=new Start();
                        }else if(Button==pauseB){
                                halt=true;
                        }
                }
        }
        class Start extends Thread{
                public Start(){
                        super();
                        start();
                }

                @Override
                public void run() {
                        try {
                                while (!halt){

                                        controlPane.startB.setEnabled(false);
                                        controlPane.forwordB.setEnabled(false);
                                        controlPane.backB.setEnabled(false);
                                        Thread.sleep(500);
                                        operation();

                                }
                                halt=false;

                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
        }


}
